﻿using System.IO.Compression;
using System.Text;

/// <summary>
/// 压缩工具类，用于按分类创建压缩包并返回流
/// </summary>
public static class ZipFileHelper
{
    public static MemoryStream CreateZippedStream(Dictionary<string, List<FileData>> filesDic)
    {
        if (filesDic == null || filesDic.Count <= 0)
            throw new Exception("下载数据为空");

        // 创建内存流作为压缩包的目标流
        var zipMemoryStream = new MemoryStream();

        // 使用using确保ZipArchive正确释放，leaveOpen设为true以保留内存流
        using (var archive = new ZipArchive(zipMemoryStream, ZipArchiveMode.Create, leaveOpen: true))
        {
            // 遍历每个分类（文件夹）
            foreach (var (dirtype, files) in filesDic)
            {
                foreach (var file in files)
                {
                    // 跳过无效文件（文件名空或内容为空）
                    if (string.IsNullOrWhiteSpace(file.FileName) || file.Content == null)
                        continue;

                    // 处理文件名（确保不包含非法字符）
                    string safeFileName = SanitizeFileName(file.FileName);

                    // 构建压缩包中的文件路径（格式：分类/文件名）
                    string entryPath = Path.Combine(dirtype, safeFileName)
                                          .Replace(Path.DirectorySeparatorChar, '/'); // 统一使用'/'作为分隔符

                    // 在压缩包中创建条目
                    var zipEntry = archive.CreateEntry(entryPath);

                    // 将文件内容写入压缩条目
                    using (var entryStream = zipEntry.Open())
                    {
                        entryStream.Write(file.Content, 0, file.Content.Length);
                    }
                }
            }
        }
        zipMemoryStream.Position = 0;
        return zipMemoryStream;

        //return zipMemoryStream;
    }
    /// <summary>
    /// 过滤文件名中的非法字符
    /// </summary>
    private static string SanitizeFileName(string fileName)
    {
        if (string.IsNullOrWhiteSpace(fileName))
            return "unknown_file";

        // 移除Windows和Zip中不允许的特殊字符
        char[] invalidChars = Path.GetInvalidFileNameChars();
        return string.Join("_", fileName.Split(invalidChars, StringSplitOptions.RemoveEmptyEntries));
    }
}

/// <summary>
/// 表示压缩包中的一个文件数据
/// </summary>
public class FileData
{
    /// <summary>
    /// 文件名（包含扩展名）
    /// </summary>
    public string FileName { get; set; }

    /// <summary>
    /// 文件内容的字节数组
    /// </summary>
    public byte[] Content { get; set; }

    /// <summary>
    /// 从字符串内容创建FileData（默认UTF8编码）
    /// </summary>
    public static FileData FromString(string fileName, string content)
    {
        return new FileData
        {
            FileName = fileName,
            Content = Encoding.UTF8.GetBytes(content)
        };
    }

    /// <summary>
    /// 从文件路径创建FileData
    /// </summary>
    public static FileData FromFile(string filePath)
    {
        return new FileData
        {
            FileName = Path.GetFileName(filePath),
            Content = File.ReadAllBytes(filePath)
        };
    }
}
